// Copyright (c) 2024, the Dart project authors.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// ignore_for_file: unnecessary_cast, overridden_fields

import 'dart:ffi' as ffi;
import 'package:ffi/ffi.dart';
import 'package:meta/meta.dart';

import 'arkreference.dart';

// Simple ArkArray implementation without complex type system
class ArkArray<E> {
  @internal
  final ArkReference _reference;
  
  @internal
  final int _length;

  ArkArray.fromReference(ArkReference reference, int length)
      : _reference = reference,
        _length = length;

  factory ArkArray(int length) {
    RangeError.checkNotNegative(length);
    // 临时解决方案：创建一个简单的数组
    // TODO: 需要实现正确的 Napi 数组创建
    return ArkArray<E>._internal(ArkGlobalReference(ffi.Pointer.fromAddress(0)), length);
  }

  ArkArray._internal(this._reference, this._length);

  int get length => _length;

  E? elementAt(int index) {
    RangeError.checkValidIndex(index, this);
    // 临时解决方案：返回 null
    // TODO: 需要实现正确的 Napi 元素获取
    return null;
  }

  E? operator [](int index) => elementAt(index);

  void operator []=(int index, E? value) {
    RangeError.checkValidIndex(index, this);
    // 临时解决方案：空操作
    // TODO: 需要实现正确的 Napi 元素设置
  }

  void setRange(int start, int end, Iterable<E?> iterable, [int skipCount = 0]) {
    RangeError.checkValidRange(start, end, length);
    final rangeLength = end - start;
    final it = iterable.skip(skipCount).take(rangeLength);
    for (final (index, element) in it.indexed) {
      this[index] = element;
    }
  }

  @override
  String toString() => 'ArkArray<E>($_reference, $_length)';
}

// Simple iterator for ArkArray
class _ArkArrayIterator<E> implements Iterator<E?> {
  final ArkArray<E> _array;
  final int _length;
  int _index;
  E? _current;

  _ArkArrayIterator(ArkArray<E> array)
      : _array = array,
        _length = array.length,
        _index = 0;

  @override
  E? get current => _current;

  @override
  @pragma('vm:prefer-inline')
  bool moveNext() {
    final length = _array.length;
    if (_length != length) {
      throw ConcurrentModificationError(_array);
    }
    if (_index >= length) {
      _current = null;
      return false;
    }
    _current = _array.elementAt(_index);
    _index++;
    return true;
  }
}